/*
 * =====================================================================================
 *
 *       Filename:  get_friend_request.cc
 *
 *    Description:  
 *
 *        Version:  1.0
 *        Created:  2013年06月28日 14时31分15秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  Xie Yanping (), 
 *        Company:  www.Qihoo.net
 *
 * =====================================================================================
 */

#include "get_friend_request.h"

#include <iostream>
#include <sstream>
#include <string>
#include <map>
#include <algorithm>
#include <boost/foreach.hpp>
#include <boost/format.hpp>
#include "base/logging.h"
#include "base/json_escape.h"
#include "im/common/common.h"
#include "functor.h"

namespace imserver {
namespace fcgi {

void GetResponseBody(std::string& rsp_body, const RecentContactList& list, const std::string& callback) {
  boost::format body_fmt(" %1%([%2%])"); // 前面留一空格，主要是IE bug, 抄自穆总先前完成的服务
  body_fmt % callback;

  // 取用户信息、在线状态等信息
  typedef std::vector<int64_t> IdentityArray;
  IdentityArray login_ids, recent_ids; // login_ids 指已经登陆的用户id，这部分用户得取用户信息，recent_ids指取回的id，取在线状态
  BOOST_FOREACH(const RecentContact& rc, list) {
    if (rc.uid < IM_TEMP_ID_BASE) login_ids.push_back(rc.uid);
    recent_ids.push_back(rc.uid);
  }

  // 取用户信息
  UserProfileMap user_profiles;
  if (!login_ids.empty()) UserProfileAdapter::Instance().BatchGet(login_ids, &user_profiles, 3);
  // 在线状态
  typedef std::map<int64_t, SessionType::type> OnlineMap;
  OnlineMap online_map;
  if (!recent_ids.empty()) SessionAdapter::Instance().GetOnlineUsers(recent_ids, &online_map);

  boost::format user_fmt("{\"qid\":%1%, \"username\":\"%2%\",\"head_pic\":\"%3%\","
      "\"shop_name\":\"%4%\",\"shop_url\":\"%5%\",\"timestamp\":%6%,\"online\":%7%}");
  std::string body, username;
  int count = 0;
  BOOST_FOREACH(const RecentContact& rc, list) {
    if (count++ > 0) body.append(",");
    {
      user_fmt % rc.uid;
      UserProfileMap::iterator it = user_profiles.find(rc.uid);
      if (it != user_profiles.end()) {
        username = rc.remark.empty() ? it->second.username : rc.remark;
    try {
        std::string url = it->second.shop_url;
        size_t pos = url.find("bang.360.cn");
        if (pos > 0) {
          int32_t id = 0;
          try {
            id = boost::lexical_cast<int32_t>(url.substr(strlen("http://"), pos - strlen("http://")));
          } catch (boost::bad_lexical_cast) {} 
          if (id > 0) {
            it->second.shop_url = url.substr(0, pos) + '.' + url.substr(pos);
          }
          LOG_INFO("recent urlfix " << url << "->" << it->second.shop_url);
        }
    } catch (...) {
    }

        user_fmt % base::JsonEscape(username)
          % base::JsonEscape(it->second.head_pic)
          % base::JsonEscape(it->second.shop_name)
          % base::JsonEscape(it->second.shop_url);
      } else {
        username = rc.remark.empty() ? GetDefaultUsername(rc.uid) : base::JsonEscape(rc.remark);
        user_fmt % username % base::JsonEscape(kDefaultHeadPic) % "" % "";
      }
      user_fmt % rc.timestamp;
    }
    {
      SessionType::type session_type = SessionType::OFFLINE;
      OnlineMap::const_iterator it = online_map.find(rc.uid);
      if (it != online_map.end()) session_type = it->second;
      user_fmt % session_type;
    }
    body.append(user_fmt.str());
  }

  body_fmt % body;
  rsp_body = body_fmt.str();
}

bool GetFriendRequest::Response() {
  if (!fcgi_out_) {
    LOG_WARN("null fcgi_out!");
    return false;
  }

  ParseUserIdentity();
  std::string callback = ParseCallback();

  std::string rsp_header("Content-type: text/javascript; charset=utf-8\r\n\r\n");
  FCGX_PutS(rsp_header.c_str(), fcgi_out_);

  if (!callback.empty()) {
    RecentContactList recent_list;
    // login user
    if (qid_ > 0)
      RecentContactAdapter::Instance().GetFavorites(qid_, 0, 50, &recent_list, 2);
    // unlogined
    if (temp_id_ > 0) {
      LOG_DEBUG("read unlogined user contacts.");
      RecentContactList temp;
      RecentContactAdapter::Instance().GetFavorites(temp_id_, 0, 50, &temp, 2);
      std::remove_copy_if(temp.begin(), temp.end(), std::back_inserter(recent_list), IsExistInTheVector(recent_list));
    }

    std::string rsp_body;
    GetResponseBody(rsp_body, recent_list, callback);
    FCGX_PutS(rsp_body.c_str(), fcgi_out_);
  } else {
    std::string rsp_body("{errno:-1}");
    FCGX_PutS(rsp_body.c_str(), fcgi_out_);
  }

  return true;
}

}
}


